www.gusucode.com > VC++ 三维图形生成和察看工具 > VC++ 三维图形生成和察看工具/code/mesh/Lib3D/Texture.cpp
//Download by http://www.NewXing.com //******************************************** // Texture.cpp //******************************************** // class CTexture //******************************************** // alliez@usc.edu // Created : 17/12/97 // Modified : 19/12/97 //******************************************** #include "stdafx.h" #include "math.h" #include "Texture.h" ////////////////////////////////////////////// // CONSTRUCTORS ////////////////////////////////////////////// //******************************************** // Constructor //******************************************** CTexture::CTexture() { m_pData = NULL; m_Width = 0; m_WidthByte32 = 0; m_Height = 0; m_Depth = 0; m_FileName = _T(""); } //******************************************** // Destructor //******************************************** CTexture::~CTexture() { Free(); } ////////////////////////////////////////////// // DATAS ////////////////////////////////////////////// //******************************************** // Alloc //******************************************** int CTexture::Alloc(unsigned int width, unsigned int height, unsigned int depth) { Free(); unsigned int BytePerPixel = (unsigned int)(depth / 8); unsigned int Width32 = WidthByte32(width,depth); // Only rgb and rgba modes ASSERT(BytePerPixel == 3 || BytePerPixel == 4); m_pData = new unsigned char [Width32 * height]; if(m_pData == NULL) { TRACE("CTexture::Alloc : Insuffisant memory\n"); AfxMessageBox("CTexture::Alloc : Insufisant memory"); return 0; } // Set members variables m_Width = width; m_WidthByte32 = Width32; m_Height = height; m_Depth = depth; UpdateHeader(); return 1; } //******************************************** // Free //******************************************** void CTexture::Free() { if(m_pData != NULL) { delete [] m_pData; m_pData = NULL; } m_Width = 0; m_Height = 0; m_Depth = 0; } ////////////////////////////////////////////// ////////////////////////////////////////////// // FILE READING ////////////////////////////////////////////// ////////////////////////////////////////////// //******************************************** // ReadFile // Redirection //******************************************** int CTexture::ReadFile(char *filename, unsigned int width, unsigned int height, unsigned int depth) { // Cleanup Free(); // Storage m_FileName = filename; // Extension CString string = filename; string.MakeLower(); TRACE("CTexture::ReadFile : file : %s\n",filename); CString extension = string.Right(4); // Redirection BMP if(extension == ".bmp") return ReadFileBMP(filename); // Redirection RAW if(extension == ".raw") return ReadFileRAW(filename,width,height,depth); // Unrecognized file format CString message; message.Format("CTexture::ReadFile : invalid file redirection : %s\n",filename); AfxMessageBox(string); return 0; } //******************************************** // ReadFileBMP (*.bmp) //******************************************** // Read windows bmp files // Accept only 24 bits // Size : 2^n x 2^m //******************************************** int CTexture::ReadFileBMP(char *filename) { // Check for valid bmp file CFile file; CFileException ex; // Try to open file if(!file.Open(filename, CFile::modeRead | CFile::typeBinary,&ex)) { #ifdef _DEBUG afxDump << "File could not be opened " << ex.m_cause << "\n"; #endif AfxMessageBox("Unable to open file for reading"); return 0; } // File header BITMAPFILEHEADER FileHeader; TRY { file.Read(&FileHeader,sizeof(BITMAPFILEHEADER)); } CATCH(CFileException, e) { #ifdef _DEBUG afxDump << "Error during reading " << e->m_cause << "\n"; #endif AfxMessageBox("Error during reading file header"); file.Close(); return 0; } END_CATCH TRACE("FileHeader.bfType : %d\n",FileHeader.bfType); TRACE("FileHeader.bfSize : %d\n",FileHeader.bfSize); TRACE("FileHeader.bfReserved1 : %d\n",FileHeader.bfReserved1); TRACE("FileHeader.bfReserved2 : %d\n",FileHeader.bfReserved2); TRACE("FileHeader.bfOffBits : %d\n",FileHeader.bfOffBits); // Is it a Windows BMP file ? (BM) WORD sign = ((WORD) ('M' << 8) | 'B'); if(FileHeader.bfType != sign) { AfxMessageBox("Invalid BMP file"); file.Close(); return 0; } // Image header TRY { file.Read(&m_Header,sizeof(BITMAPINFOHEADER)); } CATCH(CFileException, e) { #ifdef _DEBUG afxDump << "Error during reading " << e->m_cause << "\n"; #endif AfxMessageBox("Error during reading image header"); file.Close(); return 0; } END_CATCH // DEBUG TRACE("\n"); TRACE("IMAGE HEADER :\n"); TRACE("biSize : %d\n",m_Header.biSize); TRACE("biWidth : %d\n",m_Header.biWidth); TRACE("biHeight : %d\n",m_Header.biHeight); TRACE("biPlanes : %d\n",m_Header.biPlanes); TRACE("biBitCount : %d\n",m_Header.biBitCount); TRACE("biCompression : %d\n",m_Header.biCompression); TRACE("biSizeImage : %d\n",m_Header.biSizeImage); TRACE("biXPelsPerMeter : %d\n",m_Header.biXPelsPerMeter); TRACE("biYPelsPerMeter : %d\n",m_Header.biYPelsPerMeter); TRACE("biClrUsed : %d\n",m_Header.biClrUsed); TRACE("biClrImportant : %d\n",m_Header.biClrImportant); // 24 bits ? if(m_Header.biPlanes != 1 || m_Header.biBitCount != 24) { AfxMessageBox("Texture file must have 24 bits depth"); file.Close(); return 0; } // Alloc (does call Free before) Free(); m_pData = new unsigned char[m_Header.biSizeImage]; if(m_pData == NULL) { AfxMessageBox("Insuffisant memory"); file.Close(); return 0; } // Update datas m_Width = m_Header.biWidth; m_Height = m_Header.biHeight; m_Depth = m_Header.biBitCount; // Image reading TRY { file.Read(m_pData,m_Header.biSizeImage); } CATCH(CFileException, e) { #ifdef _DEBUG afxDump << "Error during reading " << e->m_cause << "\n"; #endif AfxMessageBox("Error during reading image"); file.Close(); return 0; } END_CATCH // Close file file.Close(); // Success, also set FileName m_FileName = filename; UpdateWidthByte32(); return 1; } //******************************************** // UpdateWidthByte32 //******************************************** void CTexture::UpdateWidthByte32() { m_WidthByte32 = WidthByte32(m_Width,m_Depth); } //******************************************** // WidthByte32 //******************************************** unsigned int CTexture::WidthByte32(unsigned int width, unsigned int depth) { // 32 bits alignment (4 bytes) int rest=(width*depth/8)%4; if(rest != 0) return (width*depth/8 + 4-rest); else return (width*depth/8); } //******************************************** // UpdateHeader //******************************************** void CTexture::UpdateHeader() { UpdateWidthByte32(); m_Header.biWidth = m_Width; m_Header.biHeight = m_Height; m_Header.biSizeImage = m_WidthByte32 * m_Height; m_Header.biSize = 40; m_Header.biPlanes = 1; m_Header.biBitCount = (unsigned short)m_Depth; m_Header.biCompression = 0; m_Header.biXPelsPerMeter = 0; m_Header.biYPelsPerMeter = 0; m_Header.biClrUsed = 0; m_Header.biClrImportant = 0; } //******************************************** // ReadFileRAW (*.raw) //******************************************** // Read raw files // Accept only 24 or 32 bits // Size : 2^n x 2^m //******************************************** int CTexture::ReadFileRAW(char *filename, unsigned int width, unsigned int height, unsigned int depth) { ASSERT(width>0); ASSERT(height>0); ASSERT(depth>0); ASSERT(depth%8==0); ASSERT(depth/8==3 || depth/8==4); // Check for valid file CFile file; CFileException ex; // Try to open file if(!file.Open(filename, CFile::modeRead | CFile::typeBinary,&ex)) { #ifdef _DEBUG afxDump << "File could not be opened " << ex.m_cause << "\n"; #endif AfxMessageBox("Unable to open file for reading"); return 0; } // Alloc (does call Free before) if(!Alloc(width,height,depth)) { AfxMessageBox("Insuffisant memory"); file.Close(); return 0; } // Image reading TRY { file.Read(m_pData,m_Width*m_Height*depth/8); } CATCH(CFileException, e) { #ifdef _DEBUG afxDump << "Error during reading " << e->m_cause << "\n"; #endif AfxMessageBox("Error during reading image"); file.Close(); return 0; } END_CATCH // Close file file.Close(); // Success, also set FileName m_FileName = filename; return 1; } ////////////////////////////////////////////// ////////////////////////////////////////////// // FILE SAVING ////////////////////////////////////////////// ////////////////////////////////////////////// //******************************************** // SaveFile // Redirection //******************************************** int CTexture::SaveFile(char *filename) { CString string = filename; string.MakeLower(); TRACE("CTexture::SaveFile : file : %s\n",filename); CString extension = string.Right(4); // Redirection RAW if(extension == ".raw") return SaveFileRAW(filename); // Redirection BMP if(extension == ".bmp") return SaveFileBMP(filename); // Unrecognized file format CString message; message.Format("CTexture::SaveFile : invalid file redirection : %s\n",filename); AfxMessageBox(message); return 0; } //******************************************** // SaveFileRAW //******************************************** int CTexture::SaveFileRAW(char *filename) { // Check for valid image if((m_Width * m_Height * m_Depth) == 0) { AfxMessageBox("CTexture::SaveFileRAW : invalid image"); return 0; } // Check for valid file CFile file; CFileException ex; // Try to open file if(!file.Open(filename, CFile::modeWrite | CFile::typeBinary,&ex)) { #ifdef _DEBUG afxDump << "File could not be opened " << ex.m_cause << "\n"; #endif AfxMessageBox("Unable to open file for writing"); return 0; } // Image writing TRY { file.Write(m_pData,m_Width*m_Height*m_Depth/8); } CATCH(CFileException, e) { #ifdef _DEBUG afxDump << "Error during writing " << e->m_cause << "\n"; #endif AfxMessageBox("Error during writing image"); file.Close(); return 0; } END_CATCH // Close file file.Close(); return 1; } //******************************************** // SaveFileBMP (*.bmp) //******************************************** // Save windows bmp files // Accept only 24 bits //******************************************** int CTexture::SaveFileBMP(char *filename) { if(!IsValid()) return 0; if(m_Depth != 24) return 0; // Check for valid bmp file CFile file; CFileException ex; // Try to open file if(!file.Open(filename,CFile::modeCreate | CFile::modeWrite | CFile::typeBinary,&ex)) { #ifdef _DEBUG afxDump << "File could not be opened " << ex.m_cause << "\n"; #endif AfxMessageBox("Unable to open file for writing"); return 0; } // File header BITMAPFILEHEADER FileHeader; WORD sign = ((WORD) ('M' << 8) | 'B'); FileHeader.bfType = sign; FileHeader.bfSize = 14 + 40 + m_WidthByte32*m_Height; FileHeader.bfReserved1 = 0; FileHeader.bfReserved2 = 0; FileHeader.bfOffBits = 54; TRACE("\nSave BMP File...\n"); TRACE("FileHeader.bfType : %d\n",FileHeader.bfType); TRACE("FileHeader.bfSize : %d\n",FileHeader.bfSize); TRACE("FileHeader.bfReserved1 : %d\n",FileHeader.bfReserved1); TRACE("FileHeader.bfReserved2 : %d\n",FileHeader.bfReserved2); TRACE("FileHeader.bfOffBits : %d\n",FileHeader.bfOffBits); TRY { file.Write(&FileHeader,sizeof(BITMAPFILEHEADER)); } CATCH(CFileException, e) { #ifdef _DEBUG afxDump << "Error during writing " << e->m_cause << "\n"; #endif AfxMessageBox("Error during writing file header"); file.Close(); return 0; } END_CATCH // Image header TRY { file.Write(&m_Header,sizeof(BITMAPINFOHEADER)); } CATCH(CFileException, e) { #ifdef _DEBUG afxDump << "Error during writing " << e->m_cause << "\n"; #endif AfxMessageBox("Error during writing image header"); file.Close(); return 0; } END_CATCH // DEBUG TRACE("\n"); TRACE("IMAGE HEADER :\n"); TRACE("biSize : %d\n",m_Header.biSize); TRACE("biWidth : %d\n",m_Header.biWidth); TRACE("biHeight : %d\n",m_Header.biHeight); TRACE("biPlanes : %d\n",m_Header.biPlanes); TRACE("biBitCount : %d\n",m_Header.biBitCount); TRACE("biCompression : %d\n",m_Header.biCompression); TRACE("biSizeImage : %d\n",m_Header.biSizeImage); TRACE("biXPelsPerMeter : %d\n",m_Header.biXPelsPerMeter); TRACE("biYPelsPerMeter : %d\n",m_Header.biYPelsPerMeter); TRACE("biClrUsed : %d\n",m_Header.biClrUsed); TRACE("biClrImportant : %d\n",m_Header.biClrImportant); // Image writing TRY { file.Write(m_pData,m_Header.biSizeImage); } CATCH(CFileException, e) { #ifdef _DEBUG afxDump << "Error during writing " << e->m_cause << "\n"; #endif AfxMessageBox("Error during writing image"); file.Close(); return 0; } END_CATCH // Close file file.Close(); return 1; } ////////////////////////////////////////////// ////////////////////////////////////////////// // CHECKING ////////////////////////////////////////////// ////////////////////////////////////////////// //******************************************** // IsValid //******************************************** int CTexture::IsValid() { int success = 0; success = (m_Depth == 24) || (m_Depth == 32); success &= (m_Width != 0); success &= (m_Height != 0); success &= (m_pData != NULL); if(!success) { TRACE("\n"); TRACE("Invalid texture\n"); TRACE("Width : %d\n",m_Width); TRACE("Height : %d\n",m_Height); TRACE("Depth : %d\n",m_Depth); TRACE("Data : %x\n",m_pData); } return success; } //******************************************** // HigherPowerOfTwo //******************************************** int CTexture::HigherPowerOfTwo(int value) { ASSERT(value > 0); if(value <= 0) return value; int power = 1; int x = 0; while(1) { x = (int)pow(2,power); if(x >= value) return x; power++; } return value; } //******************************************** // LowerPowerOfTwo //******************************************** int CTexture::LowerPowerOfTwo(int value) { ASSERT(value > 0); if(value <= 0) return value; int power = 1; int x = 0; while(1) { x = (int)pow(2,power); if(x >= value) return (int)pow(2,power-1); power++; } return value; } //******************************************** // SameSize //******************************************** int CTexture::SameSize(CTexture *pTexture) { int success = (m_Width == pTexture->GetWidth()); success &= (m_Height == pTexture->GetHeight()); return success; } //******************************************** // Flip BGR to RGB //******************************************** int CTexture::BGRtoRGB(void) { if(!IsValid()) return 0; unsigned char pixel; int BytePerPixel = m_Depth/8; for(unsigned int j=0;j<m_Height;j++) for(unsigned int i=0;i<m_Width;i++) { pixel = m_pData[m_WidthByte32*j+i*BytePerPixel+2]; m_pData[m_WidthByte32*j+i*BytePerPixel+2] = m_pData[m_WidthByte32*j+i*BytePerPixel]; m_pData[m_WidthByte32*j+i*BytePerPixel] = pixel; } return 1; } ////////////////////////////////////////////// ////////////////////////////////////////////// // DUPLICATE ////////////////////////////////////////////// ////////////////////////////////////////////// //******************************************** // Extract //******************************************** int CTexture::Extract(int left, int top, int right, int bottom) { ASSERT(IsValid()); // Saturate if(right == -1) right = m_Width-1; if(bottom == -1) bottom = m_Height-1; // Check if(left >= right || top >= bottom) return 0; if(left < 0 || left >= (int)m_Width || right < 0 || right >= (int)m_Width) return 0; if(top < 0 || top >= (int)m_Height || bottom < 0 || bottom >= (int)m_Height) return 0; int NewWidth = right-left+1; int NewWidthByte32 = WidthByte32(NewWidth,m_Depth); int NewHeight = bottom-top+1; int BytePerPixel = m_Depth / 8; int i,j,k; TRACE("Start extracting...\n"); TRACE("New width : %d\n",NewWidth); TRACE("New height : %d\n",NewHeight); ASSERT(NewWidth>=1); ASSERT(NewHeight>=1); // Alloc unsigned char *pData = new unsigned char[NewWidthByte32*NewHeight]; if(pData == NULL) { AfxMessageBox("Insuffisant memeory"); return 0; } for(j=0;j<NewHeight;j++) for(i=0;i<NewWidth;i++) for(k=0;k<BytePerPixel;k++) pData[NewWidthByte32*j+i*BytePerPixel+k] = m_pData[m_WidthByte32*(m_Height-1-(j+top))+(i+left)*BytePerPixel+k]; // Replace datas delete [] m_pData; m_pData = pData; m_Width = NewWidth; m_WidthByte32 = NewWidthByte32; m_Height = NewHeight; UpdateHeader(); return 1; } //******************************************** // DuplicateMirror //******************************************** int CTexture::DuplicateMirror(int left, int top, int right, int bottom) { if(!Extract(left,top,right,bottom)) return 0; left = 0; right = m_Width-1; top = 0; bottom = m_Height-1; int NewWidth = 2*m_Width; int NewWidthByte32 = WidthByte32(NewWidth,m_Depth); int NewHeight = 2*m_Height; int BytePerPixel = m_Depth / 8; int i,j,k; TRACE("Start duplicate mirror...\n"); TRACE("New width : %d\n",NewWidth); TRACE("New widthbyte32 : %d\n",NewWidthByte32); TRACE("New height : %d\n",NewHeight); ASSERT(NewWidth>=1); ASSERT(NewHeight>=1); // Alloc unsigned char *pData = new unsigned char[NewWidthByte32*NewHeight]; if(pData == NULL) { AfxMessageBox("Insuffisant memeory"); return 0; } // o o // x o for(j=0;j<NewHeight/2;j++) for(i=0;i<NewWidth/2;i++) for(k=0;k<BytePerPixel;k++) pData[NewWidthByte32*j+i*BytePerPixel+k] = m_pData[m_WidthByte32*(bottom-(j+top))+(i+left)*BytePerPixel+k]; // o o // o x for(j=0;j<NewHeight/2;j++) for(i=NewWidth/2;i<NewWidth;i++) for(k=0;k<BytePerPixel;k++) pData[NewWidthByte32*j+i*BytePerPixel+k] = m_pData[m_WidthByte32*(bottom-(j+top))+(right-(i-NewWidth/2+left))*BytePerPixel+k]; // x o // o o for(j=NewHeight/2;j<NewHeight;j++) for(i=0;i<NewWidth/2;i++) for(k=0;k<BytePerPixel;k++) pData[NewWidthByte32*j+i*BytePerPixel+k] = m_pData[m_WidthByte32*(j-NewHeight/2+top)+(i+left)*BytePerPixel+k]; // o x // o o for(j=NewHeight/2;j<NewHeight;j++) for(i=NewWidth/2;i<NewWidth;i++) for(k=0;k<BytePerPixel;k++) pData[NewWidthByte32*j+i*BytePerPixel+k] = m_pData[m_WidthByte32*(j-NewHeight/2+top)+(right-(i-NewWidth/2+left))*BytePerPixel+k]; // Replace datas delete [] m_pData; m_pData = pData; m_Width = NewWidth; m_WidthByte32 = NewWidthByte32; m_Height = NewHeight; UpdateHeader(); return 1; } //******************************************** // DuplicateRepeatWidth //******************************************** int CTexture::DuplicateRepeatWidth(int left, int top, int right, int bottom) { if(!Extract(left,top,right,bottom)) return 0; left = 0; right = m_Width-1; top = 0; bottom = m_Height-1; int NewWidth = 2*m_Width; int NewWidthByte32 = WidthByte32(NewWidth,m_Depth); int NewHeight = m_Height; int BytePerPixel = m_Depth / 8; int i,j,k; TRACE("Start duplicate mirror...\n"); TRACE("New width : %d\n",NewWidth); TRACE("New widthbyte32 : %d\n",NewWidthByte32); TRACE("New height : %d\n",NewHeight); ASSERT(NewWidth>=1); ASSERT(NewHeight>=1); // Alloc unsigned char *pData = new unsigned char[NewWidthByte32*NewHeight]; if(pData == NULL) { AfxMessageBox("Insuffisant memeory"); return 0; } // x o for(j=0;j<NewHeight;j++) for(i=0;i<NewWidth/2;i++) for(k=0;k<BytePerPixel;k++) pData[NewWidthByte32*j+i*BytePerPixel+k] = m_pData[m_WidthByte32*(bottom-(j+top))+(i+left)*BytePerPixel+k]; // o x for(j=0;j<NewHeight;j++) for(i=NewWidth/2;i<NewWidth;i++) for(k=0;k<BytePerPixel;k++) pData[NewWidthByte32*j+i*BytePerPixel+k] = m_pData[m_WidthByte32*(bottom-(j+top))+(i-NewWidth/2+left)*BytePerPixel+k]; // Replace datas delete [] m_pData; m_pData = pData; m_Width = NewWidth; m_WidthByte32 = NewWidthByte32; m_Height = NewHeight; UpdateHeader(); return 1; } ////////////////////////////////////////////// ////////////////////////////////////////////// // ALPHA ////////////////////////////////////////////// ////////////////////////////////////////////// //******************************************** // SetAlphaLayer //******************************************** int CTexture::SetAlphaLayer(unsigned char alpha) // 0 - 255 { // Check if(!IsValid()) return 0; if(m_Depth != 32) return 0; // Fill alpha layer int size = m_Width * m_Height; for(int i=0;i<4*size;i+=4) m_pData[i+3] = alpha; return 1; } //******************************************** // AddAlphaLayer //******************************************** int CTexture::AddAlphaLayer(unsigned char alpha) // 0 - 255 { // Check if(!IsValid()) return 0; // Has soon alpha if(HasAlpha()) return SetAlphaLayer(alpha); // Alloc memory unsigned char *pData = new unsigned char[4*m_Width*m_Height]; if(pData == NULL) { AfxMessageBox("CTexture::AddAlphaLayer : insuffisant memory"); return 0; } // Fill new data int size = m_Width * m_Height; int BytePerPixel = m_Depth / 8; ASSERT(size > 0); for(int i=0;i<size;i++) { pData[4*i+0] = m_pData[BytePerPixel*i+0]; pData[4*i+1] = m_pData[BytePerPixel*i+1]; pData[4*i+2] = m_pData[BytePerPixel*i+2]; pData[4*i+3] = alpha; } // Set new depth m_Depth = 32; // Replace datas delete [] m_pData; m_pData = pData; return 1; } //******************************************** // PutAlpha // From RGB to grey scales, then alpha layer //******************************************** int CTexture::PutAlpha(CTexture *pTexture) { // Check if(!IsValid()) return 0; if(!pTexture->IsValid()) return 0; if(!SameSize(pTexture)) return 0; if(!AddAlphaLayer(0)) return 0; // Fill new data unsigned char *pData = pTexture->GetData(); int size = m_Width * m_Height; int BytePerPixel = pTexture->GetDepth() / 8; ASSERT(size > 0); for(int i=0;i<size;i++) m_pData[4*i+3] = (unsigned char)(((int)pData[BytePerPixel*i+0]+ (int)pData[BytePerPixel*i+1]+ (int)pData[BytePerPixel*i+2])/3); return 1; } ////////////////////////////////////////////// ////////////////////////////////////////////// // DISPLAY ////////////////////////////////////////////// ////////////////////////////////////////////// //******************************************** // Draw //******************************************** int CTexture::Draw(CDC *pDC, int xOffset, int yOffset, int width, int height) { // Checking if(!IsValid()) return 0; // Flags if(width == -1) width = m_Width; if(height == -1) height = m_Height; // Painting return SetDIBitsToDevice(pDC->m_hDC, xOffset, yOffset, width, height, 0, 0, 0, m_Height, GetData(), (CONST BITMAPINFO *)&m_Header, DIB_RGB_COLORS); } //******************************************** // ReadBuffer //******************************************** int CTexture::ReadBuffer(unsigned char *buffer, int width, int height, int depth) { if(buffer == NULL) return 0; if(!Alloc(width,height,depth)) return 0; int BytePerPixel = depth / 8; for(int j=0;j<height;j++) for(int i=0;i<width;i++) for(int k=0;k<BytePerPixel;k++) { m_pData[m_WidthByte32*j + i*BytePerPixel+k] = buffer[(width*j+i)*BytePerPixel+k]; //TRACE("pixel : %d\n",(int)buffer[(width*j+i)*BytePerPixel+k]); } return 1; } //******************************************** // ReadBuffer //******************************************** int CTexture::ReadBuffer(float *buffer, int width, int height, int depth) { if(buffer == NULL) return 0; if(!Alloc(width,height,depth)) return 0; int BytePerPixel = depth / 8; for(int j=0;j<height;j++) for(int i=0;i<width;i++) for(int k=0;k<BytePerPixel;k++) { ASSERT(buffer[(width*j+i)*BytePerPixel+k] <= 1.0f); ASSERT(buffer[(width*j+i)*BytePerPixel+k] >= 0.0f); m_pData[m_WidthByte32*j + i*BytePerPixel+k] = (BYTE)(255.0f * buffer[(width*j+i)*BytePerPixel+k]); } return 1; } //******************************************** // Grey //******************************************** int CTexture::Grey(unsigned int x, unsigned int y) { ASSERT(x<m_Width && x>=0); ASSERT(y<m_Height && y>=0); int BytePerPixel = m_Depth / 8; // Grey scale if(BytePerPixel == 1) return (int)m_pData[m_WidthByte32*y + x]; else // 24 or 32 bits (alpha layer) return (int)((int)m_pData[m_WidthByte32*y + x*BytePerPixel+0]+ (int)m_pData[m_WidthByte32*y + x*BytePerPixel+1]+ (int)m_pData[m_WidthByte32*y + x*BytePerPixel+2])/3; } //******************************************** // Color //******************************************** void CTexture::Color(unsigned int x, unsigned int y, unsigned char *pRed, unsigned char *pGreen, unsigned char *pBlue) { ASSERT(x<m_Width && x>=0); ASSERT(y<m_Height && y>=0); int BytePerPixel = m_Depth / 8; // Grey scale if(BytePerPixel == 1) { *pRed = m_pData[m_WidthByte32*y + x]; *pGreen = m_pData[m_WidthByte32*y + x]; *pBlue = m_pData[m_WidthByte32*y + x]; } else // 24 or 32 bits (alpha layer) { *pRed = m_pData[m_WidthByte32*y + x*BytePerPixel]; *pGreen = m_pData[m_WidthByte32*y + x*BytePerPixel+1]; *pBlue = m_pData[m_WidthByte32*y + x*BytePerPixel+2]; } } HANDLE CTexture::ExportHandle() { HANDLE handle; TRACE("Export handle..."); // Process source handle size int size = sizeof(BITMAPINFOHEADER) + m_WidthByte32 * m_Height; // Alloc memory TRACE("alloc..."); handle = (HANDLE)::GlobalAlloc (GHND,size); if(handle != NULL) { char *pData = (char *) ::GlobalLock((HGLOBAL)handle); TRACE("lock..."); // Copy header TRACE("header..."); memcpy(pData,&m_Header,sizeof(BITMAPINFOHEADER)); // Copy datas TRACE("datas..."); memcpy(pData+sizeof(BITMAPINFOHEADER),m_pData,m_WidthByte32*m_Height); // Unlock TRACE("unlock..."); ::GlobalUnlock((HGLOBAL)handle); } TRACE("ok\n"); return handle; } // ** EOF **